<template>
  <div class="flex-column">
    <sticky :className="'sub-navbar'">
      <div class="filter-container">
        <el-input @keyup.enter.native="handleFilter" size="mini" prefix-icon="el-icon-search"
          style="width: 200px;margin-bottom: 0;" class="filter-item" :placeholder="'关键字'" v-model="listQuery.key">
        </el-input>

        <permission-btn  :size="'mini'" v-on:btn-event="onBtnClicked"></permission-btn>

        <el-checkbox size="mini" class="m-l-15" @change='tableKey=tableKey+1' v-model="showDescription">Id/描述
        </el-checkbox>
      </div>
    </sticky>
    <div class="app-container flex-item">
      <el-row class="fh">
        <el-col :span="10" class="fh ls-border">
          <el-card shadow="never" class="card-body-none fh" style="overflow-y: auto">
            <div slot="header" class="clearfix">
              <el-button type="text" style="padding: 0 11px" @click="getAllMenus">所有菜单>></el-button>
            </div>
            <tree-table ref="menuTable" highlight-current-row :data="modulesTree" :columns="columns" @row-click="treeClick" border>
            </tree-table>
          </el-card>
        </el-col>
        <el-col :span="14" class="fh">
          <div class="bg-white fh">
            <el-table ref="mainTable" :key='tableKey' :data="currentPageMenus" v-loading="listLoading" border fit
              highlight-current-row style="width: 100%;" height="calc(100% - 52px)" @row-click="rowClick"
              @selection-change="handleSelectionChange">
              <el-table-column type="selection" align="center" width="55">
              </el-table-column>

              <el-table-column :label="'Id'" v-if="showDescription" min-width="120px">
                <template slot-scope="scope">
                  <span>{{scope.row.id}}</span>
                </template>
              </el-table-column>

              <el-table-column min-width="80px" :label="'DOM ID'">
                <template slot-scope="scope">
                  <span class="link-type" @click="handleEditMenu(scope.row)">{{scope.row.domId}}</span>
                </template>
              </el-table-column>

              <el-table-column min-width="50px" :label="'名称'">
                <template slot-scope="scope">
                  <span>{{scope.row.name}}</span>
                </template>
              </el-table-column>

              <el-table-column min-width="30px" :label="'排序'">
                <template slot-scope="scope">
                  <span>{{scope.row.sort}}</span>
                </template>
              </el-table-column>

              <el-table-column min-width="80px" :label="'样式'">
                <template slot-scope="scope">
                  <span>{{scope.row.class}}</span>
                </template>
              </el-table-column>
              <el-table-column min-width="80px" :label="'ICON'">
                <template slot-scope="scope">
                  <span>{{scope.row.icon}}</span>
                </template>
              </el-table-column>

              <el-table-column :label="'描述'" v-if="showDescription" min-width="120px">
                <template slot-scope="scope">
                  <span>{{scope.row.remark}}</span>
                </template>
              </el-table-column>
            </el-table>
            <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit"
              @pagination="handleCurrentChange" />
          </div>
        </el-col>
      </el-row>


      <!--模块编辑对话框-->
      <el-dialog v-el-drag-dialog class="dialog-mini" width="500px" :title="textMap[dialogStatus]"
        :visible.sync="dialogFormVisible">
        <el-form :rules="rules" ref="dataForm" :model="temp" label-position="right" label-width="100px">
          <el-form-item size="small" :label="'Id'" prop="id" v-show="dialogStatus=='update'">
            <span>{{temp.id}}</span>
          </el-form-item>
          <el-form-item size="small" :label="'层级ID'" v-show="dialogStatus=='update'">
            <span>{{temp.cascadeId}}</span>
          </el-form-item>
          <el-form-item size="small" :label="'名称'" prop="name">
            <el-input v-model="temp.name"></el-input>
          </el-form-item>
          <el-form-item size="small" :label="'排序'">
            <el-input-number v-model="temp.sortNo" :min="1" :max="20"></el-input-number>
          </el-form-item>
          <el-form-item size="small" :label="'是否系统'" prop="isSys">
            <el-switch v-model="temp.isSys" active-color="#13ce66" inactive-color="#ff4949">
            </el-switch>
          </el-form-item>
          <el-form-item size="small" :label="'模块标识'">
            <el-input v-model="temp.code"></el-input>
          </el-form-item>
          <el-form-item size="small" :label="'图标'">
            <el-popover placement="top-start" width="500" ref="popoverModule" trigger="click" content="">
              <el-input slot="reference"
                :class="temp.iconName ? `iconfont icon-${temp.iconName} custom-icon-input` : ''"
                v-model="temp.iconName"></el-input>
              <el-row class="selectIcon-box">
                <el-col :class="{'active': temp.iconName === item.font_class}" :span="3"
                  v-for="(item,index) in iconData.glyphs" :key="index">
                  <i :class="`${iconData.font_family} ${iconData.css_prefix_text}${item.font_class}`"
                    @click="handleChangeTempIcon(item)"></i>
                </el-col>
              </el-row>
            </el-popover>
          </el-form-item>
          <el-form-item size="small" :label="'url'">
            <el-input v-model="temp.url"></el-input>
          </el-form-item>

          <el-form-item size="mini" :label="'上级机构'">

            <treeselect ref="modulesTree" :normalizer="normalizer" :disabled="treeDisabled" :options="modulesTreeRoot"
              :default-expand-level="3" :multiple="false" :open-on-click="true" :open-on-focus="true"
              :clear-on-select="true" v-model="dpSelectModule"></treeselect>
          </el-form-item>
        </el-form>
        <div slot="footer">
          <el-button size="mini" @click="dialogFormVisible = false">取消</el-button>
          <el-button size="mini" v-if="dialogStatus=='create'" type="primary" @click="createData">确认</el-button>
          <el-button size="mini" v-else type="primary" @click="updateData">确认</el-button>
        </div>
      </el-dialog>
      <!--菜单编辑对话框-->
      <el-dialog v-el-drag-dialog class="dialog-mini" width="500px" :title="textMap[dialogMenuStatus]"
        :visible.sync="dialogMenuVisible">
        <el-form :rules="rules" ref="menuForm" :model="menuTemp" label-position="right" label-width="100px">
          <el-form-item size="small" :label="'Id'" prop="id" v-show="dialogMenuStatus=='update'">
            <span>{{menuTemp.id}}</span>
          </el-form-item>

          <el-form-item size="small" :label="'名称'" prop="name">
            <el-input v-model="menuTemp.name"></el-input>
          </el-form-item>
          <el-form-item size="small" :label="'DOM ID'">
            <el-input v-model="menuTemp.domId"></el-input>
          </el-form-item>
          <el-form-item size="small" :label="'样式'" style="position:relative;">
            <el-button :type="menuTemp.class" class="custom-select-icon" size="mini"></el-button>
            <el-select style="width: 100%;" v-model="menuTemp.class" placeholder="请选择">
              <el-option
                v-for="item in classBtns"
                :key="item.value"
                :label="item.value"
                :value="item.value">
                <span style="float: left">{{ item.value }}</span>
                <span style="float: right; color: #8492a6; font-size: 13px">
                  <el-button :type="item.value" size="mini"></el-button>
                </span>
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item size="small" :label="'图标'">
            <el-popover placement="top-start" width="500" trigger="click" ref="popoverMenu">
              <el-input slot="reference"
                :class="menuTemp.icon ? `iconfont icon-${menuTemp.icon} custom-icon-input` : ''"
                v-model="menuTemp.icon"></el-input>
              <el-row class="selectIcon-box">
                <el-col :class="{'active': menuTemp.icon === item.font_class}" :span="3"
                  v-for="(item,index) in iconData.glyphs" :key="index">
                  <i :class="`${iconData.font_family} ${iconData.css_prefix_text}${item.font_class}`"
                    @click="handleChangeMenuTempIcon(item)"></i>
                </el-col>
              </el-row>
            </el-popover>
          </el-form-item>
          <el-form-item size="small" :label="'排序'">
            <el-input-number v-model="menuTemp.sort" :min="0" :max="10"></el-input-number>
          </el-form-item>
          <el-form-item size="small" :label="'备注'">
            <el-input v-model="menuTemp.remark"></el-input>
          </el-form-item>
          <el-form-item size="small" :label="'所属模块'">

            <treeselect ref="menuModulesTree" :normalizer="normalizer" :options="modulesTree" :default-expand-level="3"
              :multiple="false" :open-on-click="true" :open-on-focus="true" :clear-on-select="true"
              v-model="menuTemp.moduleId"></treeselect>
          </el-form-item>
        </el-form>
        <div slot="footer">
          <el-button size="mini" @click="dialogMenuVisible = false">取消</el-button>
          <el-button size="mini" v-if="dialogMenuStatus=='create'" type="primary" @click="addMenu">确认</el-button>
          <el-button size="mini" v-else type="primary" @click="updateMenu">确认</el-button>
        </div>
      </el-dialog>
    </div>
  </div>

</template>

<script>
  import treeTable from '@/components/TreeTable'
  import Pagination from '@/components/Pagination'
  import {
    listToTreeSelect
  } from '@/utils'
  import extend from "@/extensions/delRows.js"
  import * as modules from '@/api/modules'
  import * as login from '@/api/login'
  import Treeselect from '@riophae/vue-treeselect'
  import '@riophae/vue-treeselect/dist/vue-treeselect.css'
  import waves from '@/directive/waves' // 水波纹指令
  import Sticky from '@/components/Sticky'
  import permissionBtn from '@/components/PermissionBtn'
  import elDragDialog from '@/directive/el-dragDialog'
  import iconData from '@/assets/public/css/comIconfont/iconfont.json'
  export default {
    name: 'module',
    components: {
      Sticky,
      permissionBtn,
      Treeselect,
      treeTable,
      Pagination
    },
    mixins: [extend],
    directives: {
      waves,
      elDragDialog
    },
    data() {
      return {
        iconData: iconData,
        classBtns: [{
          value: 'primary'
        },{
          value: 'danger'
        },{
          value: 'success'
        },{
          value: 'info'
        },{
          value: 'warning'
        }], // 按钮样式
        normalizer(node) {
          // treeselect定义字段
          return {
            label: node.name,
            id: node.id,
            children: node.children
          }
        },
        columns: [
          // treetable的列名
          {
            text: '模块名称',
            value: 'name'
          },
          {
            text: '模块标识',
            value: 'code'
          },
          {
            text: 'URL',
            value: 'url'
          }
        ],
        selectMenus: [], // 菜单列表选中的值
        tableKey: 0,
        list: [], // 菜单列表
        total: 0,
        currentModule: null, // 左边模块treetable当前选中的项
        listLoading: false,
        listQuery: {
          // 查询条件
          page: 1,
          limit: 20,
          orgId: '',
          key: undefined
        },
        apps: [],

        showDescription: false,
        modules: [], // 用户可访问到的模块列表
        modulesTree: [], // 用户可访问到的所有模块组成的树
        temp: {
          // 模块临时值
          id: undefined,
          cascadeId: '',
          url: '',
          code: '',
          sortNo: 0,
          iconName: '',
          parentId: null,
          name: '',
          status: 0,
          isSys: false
        },
        menuTemp: {
          // 菜单临时值
          id: undefined,
          url: '',
          icon: '',
          code: '',
          moduleId: null,
          name: '',
          status: 0,
          sort: 0
        },
        lastParentId:'',  //最后一次选中的上级模块Id
        dialogFormVisible: false, // 模块编辑框
        dialogStatus: '',
        dialogMenuVisible: false, // 菜单编辑框
        dialogMenuStatus: '',

        chkRoot: false, // 根节点是否选中
        treeDisabled: false, // 树选择框时候可用
        textMap: {
          update: '编辑',
          create: '添加'
        },
        rules: {
          name: [{
            required: true,
            message: '名称不能为空',
            trigger: 'blur'
          }]
        },
        downloadLoading: false
      }
    },
    computed: {
      isRoot: {
        get() {
          return this.chkRoot
        },
        set(v) {
          this.chkRoot = v
          if (v) {
            this.temp.parentName = '根节点'
            this.temp.parentId = null
          }
        }
      },
      modulesTreeRoot() {
        const root = [{
          name: '根节点',
          parentId: '',
          id: ''
        }]
        return root.concat(this.modulesTree)
      },
      currentPageMenus: {
        get() {
          var start = (this.listQuery.page - 1) * this.listQuery.limit
          var end = (this.listQuery.page * this.listQuery.limit)
          var result = this.list.slice(start, end)
          return result
        }
      },
      dpSelectModule: {
        // 模块编辑框下拉选中的模块
        get: function () {
          if (this.dialogStatus === 'update') {
            return this.temp.parentId || ''
          } else {
            return this.lastParentId
          }
        },
        set: function (v) {
          if (v === undefined || v === null || !v) {
            // 如果是根节点
            this.temp.parentName = '根节点'
            this.temp.parentId = null
            return
          }
          this.temp.parentId = v
          this.lastParentId = v
          var parentname = this.modules.find(val => {
            return v === val.id
          }).name
          this.temp.parentName = parentname
        }
      }
    },
    filters: {
      statusFilter(status) {
        const statusMap = {
          0: 'info',
          1: 'danger'
        }
        return statusMap[status]
      }
    },
    created() {
      // this.getList()
    },
    mounted() {
      this.getModulesTree()
    },
    methods: {
      handleChangeTempIcon(item) {
        this.temp.iconName = item.font_class
        this.$refs.popoverModule.doClose()
      },
      handleChangeMenuTempIcon(item) {
        this.menuTemp.icon = item.font_class
        this.$refs.popoverMenu.doClose()
      },
      rowClick(row) {
        this.$refs.mainTable.clearSelection()
        this.$refs.mainTable.toggleRowSelection(row)
      },
      treeClick(data) {
        // 左侧treetable点击事件
        this.currentModule = data
        this.currentModule.parent = null
        this.getList()
      },
      getAllMenus() {
        this.currentModule = null
        this.getList()
      },
      handleSelectionChange(val) {
        this.selectMenus = val
      },
      onBtnClicked: function (domId) {
        console.log('you click:' + domId)
        switch (domId) {
          case 'btnAdd':
            this.handleCreate()
            break
          case 'btnEdit':
            if (this.currentModule === null) {
              this.$message({
                message: '只能选中一个进行编辑',
                type: 'error'
              })
              return
            }
            this.handleUpdate(this.currentModule)
            break
          case 'btnDel':
            if (this.currentModule === null) {
              this.$message({
                message: '至少删除一个',
                type: 'error'
              })
              return
            }
            this.handleDelete(this.currentModule)
            break
          case 'btnAddMenu':
            this.handleAddMenu()
            break
          case 'btnEditMenu':
            if (this.selectMenus.length !== 1) {
              this.$message({
                message: '只能选中一个进行编辑',
                type: 'error'
              })
              return
            }
            this.handleEditMenu(this.selectMenus[0])
            break
          case 'btnDelMenu':
            if (this.selectMenus.length < 1) {
              this.$message({
                message: '至少删除一个',
                type: 'error'
              })
              return
            }
            this.handleDelMenus(this.selectMenus)
            break
          default:
            break
        }
      },
      getList() {
        this.listLoading = true
        var moduleId = this.currentModule === null ? null : this.currentModule.id
        modules.loadMenus(moduleId).then(response => {
          this.list = response.result
          this.total = response.result.length
          this.listLoading = false
        })
      },
      getModulesTree() {
        var _this = this // 记录vuecomponent
        login.getModules().then(response => {
          _this.modules = response.result.map(function (item) {
            return {
              sortNo: item.sortNo,
              id: item.id,
              name: item.name,
              iconName: item.iconName,
              parentId: item.parentId || null,
              code: item.code,
              url: item.url,
              cascadeId: item.cascadeId,
              isSys: item.isSys
            }
          })
          var modulestmp = JSON.parse(JSON.stringify(_this.modules))


          
          _this.modulesTree = listToTreeSelect(modulestmp).sort((a, b) => a.sortNo - b.sortNo)



          const arr = _this.modulesTree.filter(item => item.children && item.children.length > 0)
          // 默认选中第一个
          _this.$refs.menuTable.rowClick(arr[0].children[0])
        })
      },
      handleFilter() {
        this.listQuery.page = 1
        this.getList()
      },
      handleSizeChange(val) {
        this.listQuery.limit = val
        this.getList()
      },
      handleCurrentChange(val) {
        this.listQuery.page = val.page
        this.listQuery.limit = val.limit
        this.getList()
      },
      resetTemp() {
        this.temp = {
          id: undefined,
          cascadeId: '',
          url: '',
          iconName: '',
          code: '',
          parentId: null,
          name: '',
          status: 0
        }
      },
      resetMenuTemp() {
        this.menuTemp = {
          id: undefined,
          cascadeId: '',
          icon: '',
          url: '',
          code: '',
          moduleId: this.currentModule ? this.currentModule.id : null,
          name: '',
          status: 0,
          sort: 0
        }
      },

      // #region 模块管理
      handleCreate() {  // 弹出添加框
        
        this.dpSelectModule = this.lastParentId  
        this.resetTemp()
        this.dialogStatus = 'create'
        this.dialogFormVisible = true
        this.$nextTick(() => {
          this.$refs['dataForm'].clearValidate()
        })
      },
      createData() {
        // 保存提交
        this.$refs['dataForm'].validate(valid => {
          var _this = this
          if (valid) {
            if (_this.temp.url.indexOf('http') > -1 && !_this.temp.code) {
              _this.$message.error('请输入模块标识')
              return
            }
            //如果打开弹框后，没有做任何选择操作，父级为空
            _this.temp.parentId = _this.temp.parentId || _this.lastParentId

            modules.add(_this.temp).then(response => {
              // 需要回填数据库生成的数据
              _this.temp.id = response.result.id
              _this.temp.cascadeId = response.result.cascadeId
              _this.list.unshift(_this.temp)
              _this.dialogFormVisible = false
              _this.$notify({
                title: '成功',
                message: '创建成功',
                type: 'success',
                duration: 2000
              })
              _this.getModulesTree()
            })
          }
        })
      },
      handleUpdate(row) {
        // 弹出编辑框
        this.temp = Object.assign({}, row) // copy obj
        if (this.temp.children) { // 点击含有子节点树结构时，带有的children会造成提交的时候json死循环
          this.temp.children = null
        }

        this.dialogStatus = 'update'
        this.dialogFormVisible = true
        this.dpSelectModule = this.temp.parentId
        this.$nextTick(() => {
          this.$refs['dataForm'].clearValidate()
        })
      },
      updateData() {
        // 更新提交
        this.$refs['dataForm'].validate(valid => {
          if (valid) {
            const tempData = Object.assign({}, this.temp)
            if (tempData.url.indexOf('http') > -1 && !tempData.code) {
              this.$message.error('请输入模块标识')
              return
            }
            modules.update(tempData).then(() => {
              this.dialogFormVisible = false
              this.$notify({
                title: '成功',
                message: '更新成功',
                type: 'success',
                duration: 2000
              })

              this.getModulesTree()
              for (const v of this.list) {
                if (v.id === this.temp.id) {
                  const index = this.list.indexOf(v)
                  this.list.splice(index, 1, this.temp)
                  break
                }
              }
            })
          }
        })
      },
      handleDelete(row) {
        var _this = this
        _this.delrows(modules, [row], () => {
          _this.getModulesTree()
        })
      },
      // #end region

      // #region 菜单管理
      handleAddMenu() {
        // 弹出添加框
        this.resetMenuTemp()
        this.dialogMenuStatus = 'create'
        this.dialogMenuVisible = true
        this.$nextTick(() => {
          this.$refs['menuForm'].clearValidate()
        })
      },
      addMenu() {
        // 保存提交
        this.$refs['menuForm'].validate(valid => {
          if (valid) {
            modules.addMenu(this.menuTemp).then(response => {
              // 需要回填数据库生成的数据
              this.menuTemp.id = response.result.id
              this.list.unshift(this.menuTemp)
              this.dialogMenuVisible = false
              this.$notify({
                title: '成功',
                message: '创建成功',
                type: 'success',
                duration: 2000
              })
            })
          }
        })
      },
      handleEditMenu(row) {
        // 弹出编辑框
        this.menuTemp = Object.assign({}, row) // copy obj
        this.dialogMenuStatus = 'update'
        this.dialogMenuVisible = true
        this.$nextTick(() => {
          this.$refs['menuForm'].clearValidate()
        })
      },
      updateMenu() {
        // 更新提交
        this.$refs['menuForm'].validate(valid => {
          if (valid) {
            const tempData = Object.assign({}, this.menuTemp)
            modules.updateMenu(tempData).then(() => {
              this.dialogMenuVisible = false
              this.$notify({
                title: '成功',
                message: '更新成功',
                type: 'success',
                duration: 2000
              })

              for (const v of this.list) {
                if (v.id === this.menuTemp.id) {
                  const index = this.list.indexOf(v)
                  this.list.splice(index, 1, this.menuTemp)
                  break
                }
              }
            })
          }
        })
      },
      handleDelMenus(rows) {
        // 多行删除
        modules.delMenu(rows.map(u => u.id)).then(() => {
          this.$notify({
            title: '成功',
            message: '删除成功',
            type: 'success',
            duration: 2000
          })
          rows.forEach(row => {
            const index = this.list.indexOf(row)
            this.list.splice(index, 1)
          })
        })
      }
      // #end region
    }
  }
</script>

<style lang="scss">
  .text {
    font-size: 14px;
  }

  .item {
    margin-bottom: 18px;
  }

  .clearfix:before,
  .clearfix:after {
    display: table;
    content: '';
  }

  .clearfix:after {
    clear: both;
  }

  .el-card__header {
    padding: 12px 20px;
  }

  .selectIcon-box {
    text-align: center;
    border: 1px solid #eeeeee;
    border-right: 0;
    border-bottom: 0;

    .el-col {
      padding: 10px 0;
      border-right: 1px solid #eeeeee;
      border-bottom: 1px solid #eeeeee;

      &.active {
        .iconfont {
          color: #409EFF;
        }
      }
    }

    .iconfont {
      cursor: pointer;
      font-size: 20px;
    }
  }

  .custom-icon-input::before {
    font-size: 18px;
    position: absolute;
    right: 10px;
    top: 8px;
  }
  .custom-select-icon{
    position: absolute;
    top: 8px;
    right:40px;
    z-index: 10;
  }
</style>